package com.seanzx.resolver;

import com.seanzx.common.Result;
import com.seanzx.common.ResultCode;
import com.seanzx.lexical.LexicalAnalyzer;
import com.seanzx.lexical.Token;
import com.seanzx.resolver.impl.*;

import java.util.ArrayList;
import java.util.List;

public class ResolverChain {
    private static final ResolverChain SINGLETON = new ResolverChain();
    private final List<IResolver<?>> resolvers = new ArrayList<>();

    static {
        SINGLETON.add(new CreateDatabaseResolver());
        SINGLETON.add(new ShowDatabaseResolver());
        SINGLETON.add(new UseDatabaseResolver());
        SINGLETON.add(new DropDatabaseResolver());
        SINGLETON.add(new CreateTableResolver());
        SINGLETON.add(new DropTableResolver());
        SINGLETON.add(new DeleteDataResolver());
        SINGLETON.add(new InsertDataResolver());
        SINGLETON.add(new SelectDataResolver());
        SINGLETON.add(new ShowVariablesResolver());
        SINGLETON.add(new ShowVariablesResolver());
        SINGLETON.add(new GetVariableResolver());
        SINGLETON.add(new SetVariableResolver());
    }

    public static ResolverChain get() {
        return SINGLETON;
    }

    public <T> void add(IResolver<T> translator) {
        resolvers.add(translator);
    }

    public Result tryTranslate(String sql) {
        List<Token> tokens = LexicalAnalyzer.analysis(sql.toCharArray());
        for (IResolver<?> resolver : resolvers) {
            if (resolver.matches(tokens)) {
                Object transResult = resolver.translate(tokens);
                if (resolver.validate(transResult)) {
                    return resolver.access(transResult);
                }
                break;
            }
        }
        return Result.of(ResultCode.SQL_ANALYSIS_FAILED);
    }

    public static void main(String[] args) {
        System.out.println(ResolverChain.get().tryTranslate("SHOW DATABASES"));
        System.out.println(ResolverChain.get().tryTranslate("CREATE DATABASE sean_db"));
        System.out.println(ResolverChain.get().tryTranslate("SHOW DATABASES"));
        System.out.println(ResolverChain.get().tryTranslate("USE sean_db"));
        System.out.println(ResolverChain.get().tryTranslate("CREATE TABLE `sean_tbl` ( " +
                "id INT(11) COMMENT '主键' ," +
                "name VARCHAR(255) COMMENT '名称'," +
                "age INT(11) COMMENT '年龄'," +
                "description VARCHAR(255) COMMENT '描述'" +
                ");"));
        System.out.println(ResolverChain.get().tryTranslate("DELETE FROM sean_tbl WHERE id = 1"));
    }
}
